#! /usr/local/bin/python3

"""
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""

"""
njpick3-lottery.py

This a script for keeping track of the new jersey pick3 lottery. Add players
according to the digit they represent, 0-9. this script will keep score up to
the win value. Be sure to add a start date integer formatted like YYYYMMDD.
"""

import os
import sys
import urllib.parse
import urllib.request
import re
from datetime import date 
from datetime import timedelta 
from hashlib import sha1 as sha1

pick3_data = "http://www.state.nj.us/lottery/data/pick3.dat"

players = ['Ringo','George','Paul','John','Dick','Jane','Ralph','Fonz','Richie','Leather']
start   = 20100108
win     = 40
output  = "/usr/local/apache2.2/htdocs/lottery.txt"


def getDate(date_int):
    date_str = str(date_int)
    y = int(date_str[:4])
    m = int(date_str[4] + date_str[5])
    d = int(date_str[-2:])
    return date(y,m,d)


req = urllib.request.Request(pick3_data,data=None,headers={})
totals = {'0':0,'1':0,'2':0,'3':0,'4':0,'5':0,'6':0,'7':0,'8':0,'9':0} 
draws  = {}

# find the player with the most amount of chars
longest = 0
for name in players:
    if(longest > len(name)):
        continue
    longest = len(name)

try:
    response = urllib.request.urlopen(req)
    FILE = open(output,"w")
except urllib.request.HTTPError as e:
    print(e.read())
    sys.exit()

# Parse response
while True:
    line = response.readline()
    if not line:
        break

    row = line.decode().split('%')

    # We aren't concerned with alot of these dates
    # Break out if the dates start to get less than
    # start because the pick3.dat file is ordered
    # desc. If the order were asc, then change break
    # to continue
    if(row[3] != 'Z'):
        continue
    elif(int(row[0]+row[1]+row[2]) < start):
        break 

    # use dates like 20100107 as keys and the pick3 as values
    draws[int(row[0]+row[1]+row[2])] = [row[5],row[6],row[7]]

# sort dates
dates = list(draws.keys())
dates.sort()

# get totals
got_winner = False
for i in dates:
    digit_1 = draws[i][0]
    digit_2 = draws[i][1]
    digit_3 = draws[i][2]

    for t in totals:
        if(totals[t] == win):
            got_winner = True

    if(got_winner):
        del draws[i] 
    else:
        # Each digit from the pick3 is a key
        totals[digit_1] += 1
        totals[digit_2] += 1
        totals[digit_3] += 1



# totals sorted by value
totals_sorted = sorted(totals.items(), key=lambda x: x[1])
totals_sorted.reverse()


format = "%"+str(longest)+"s(%s)  %3s %s %s\n"
for k in totals_sorted:
    percent = int((k[1]/win)*100)
    graph = "-"*100
    
    FILE.write( format % (players[int(k[0])], k[0], k[1], "+"*percent + graph[percent:], str(win-k[1] )) )

FILE.write("\n")

# Clear totals
totals = {'0':0,'1':0,'2':0,'3':0,'4':0,'5':0,'6':0,'7':0,'8':0,'9':0} 
count = 1
# sort dates
dates = list(draws.keys())
dates.sort()
dates.reverse()
num_of_draws = len(dates)
three_name_width = longest*3+20

FILE.write("="*(43+three_name_width))
FILE.write("\n")
row_format = "| %9s | %-16s | %5s | %-"+str(three_name_width)+"s |\n"
FILE.write(row_format % ("# of draw", "Date", "Pick3", "  Points"))
FILE.write("="*(43+three_name_width))
FILE.write("\n")

# Fill the totals
for i in dates:
    digit_1 = draws[i][0]
    digit_2 = draws[i][1]
    digit_3 = draws[i][2]

    # Each digit from the pick3 is a key
    totals[digit_1] += 1
    totals[digit_2] += 1
    totals[digit_3] += 1

padding = str(longest)
person_format = "%-"+padding+"s %-2s"
for i in dates:
    digit_1 = draws[i][0]

    persons = "  "
    persons += person_format % ( players[int(digit_1)],str(totals[digit_1]) )
    seen = [digit_1]

    digit_2 = draws[i][1]
    if(digit_2 in seen):
        pass
    else:
        persons += ",  "
        persons += person_format % ( players[int(digit_2)],str(totals[digit_2]) )
        seen.append(digit_2)

    digit_3 = draws[i][2]
    if(digit_3 in seen):
        pass
    else:
        persons += ",  "
        persons += person_format % ( players[int(digit_3)],str(totals[digit_3]) )

    # Each digit from the pick3 is a key
    totals[digit_1] -= 1
    totals[digit_2] -= 1
    totals[digit_3] -= 1

    d = getDate(i)
    FILE.write(row_format % (num_of_draws, d.strftime("%a, %d %b %Y"), "".join(draws[i]), persons))
    num_of_draws -= 1

FILE.write("="*(43+three_name_width))
FILE.close()

